package Log

import (
	"context"
	"log"
	"sync"

	"github.com/go-redis/redis/v8"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

type syncRedisStreamWriter struct {
	client   *redis.Client
	pipe     redis.Pipeliner // 修改为 redis.Pipeliner 接口
	count    int
	maxCount int
	mutex    sync.Mutex
}

func newSyncRedisStreamWriter() *syncRedisStreamWriter {
	client := redis.NewClient(&redis.Options{
		Addr: "localhost:6379",
	})
	return &syncRedisStreamWriter{
		client:   client,
		maxCount: 1,
	}
}

func (w *syncRedisStreamWriter) Write(p []byte) (n int, err error) {
	w.mutex.Lock()
	defer w.mutex.Unlock()

	if w.pipe == nil {
		w.pipe = w.client.Pipeline() // 这里直接赋值，因为 w.pipe 是 Pipeliner 接口
		if w.pipe == nil {
			return 0, nil // 如果创建管道失败，返回适当的错误处理（这里可能不会发生，因为 Pipeline 几乎总是返回一个非 nil 的值）
		}
	}

	w.pipe.XAdd(context.Background(), &redis.XAddArgs{
		Stream: "adminLogsStream",
		Values: map[string]interface{}{"log": string(p)},
	})
	w.count++

	if w.count >= w.maxCount {
		_, err = w.pipe.Exec(context.Background())
		w.pipe = nil
		w.count = 0
		if err != nil {
			return 0, err
		}
	}

	return len(p), nil
}

func (w *syncRedisStreamWriter) Sync() error {
	w.mutex.Lock()
	defer w.mutex.Unlock()

	if w.pipe != nil && w.count > 0 {
		_, err := w.pipe.Exec(context.Background())
		w.pipe = nil
		w.count = 0
		if err != nil {
			return err
		}
	}

	return nil
}

func (w *syncRedisStreamWriter) Close() error {
	return w.client.Close()
}

func InitLoggerWithRedisStream() *zap.Logger {
	logger, err := zap.NewProduction()
	if err != nil {
		log.Fatal(err)
	}

	syncWriter := newSyncRedisStreamWriter()

	// 尝试删除流
	err = syncWriter.client.Del(context.Background(), "adminLogsStream").Err()
	if err != nil {
		log.Println("Error deleting stream (might be okay if stream didn't exist):", err)
	}

	logger = logger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
		return zapcore.NewCore(zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), syncWriter, zap.InfoLevel)
	}))

	// 创建消费者组
	_, err = syncWriter.client.XGroupCreateMkStream(context.Background(), "adminLogsStream", "your_group", "0").Result()
	if err != nil {
		log.Println("Error creating consumer group:", err)
	}

	return logger
}
